<?php

/**
 * Created by PhpStorm.
 * Author: QinShuai
 * Email: qinshuai0423@qq.com
 * Date: 2021/6/25
 */

namespace backend\behaviors;

use backend\models\AdminRule;
use backend\models\AdminUser;
use Yii;
use yii\base\Controller;
use yii\db\Exception;
use yii\web\User;

/**
 * Class AdminAuthBehavior
 * @package backend\behaviors
 */
class AdminAuthBehavior extends \yii\base\Behavior
{
    /**
     * 菜单缓存key
     */
    const MENU_KEY = 'menu:key';
    const AUTH_RULES = 'auth:rules';
    const AUTH_RIDS = 'auth:rids';

    public function events()
    {
        return [
            Controller::EVENT_BEFORE_ACTION => 'beforeAction',
            User::EVENT_AFTER_LOGIN => 'afterLogin'
        ];
    }

    public function beforeAction()
    {
        $this->checkAuth();
    }

    /**
     * 检查权限
     * @return bool
     * @throws Exception
     */
    public function checkAuth()
    {
        $userId = Yii::$app->user->id;
        if ($userId == 1) {
            return true;
        }
        //检查方法
        $pathInfo = Yii::$app->request->pathInfo ?: '/index/index';
        $pathInfo = trim($pathInfo, '/',);
        if (strpos($pathInfo, '/') == false) {
            $pathInfo = $pathInfo . '/index';
        }
        $authRule = Yii::$app->session->get(self::AUTH_RULES);
        if (isset($authRule['/' . $pathInfo]) || isset($authRule[$pathInfo]) || isset($authRule['/' . $pathInfo])) {
            return true;
        }
        if (Yii::$app->request->isAjax) {
            echo json_encode(['code' => 1, 'message' => '抱歉！您没有此操作权限！']);
            die;
        }
        throw new Exception('抱歉！您没有此操作权限');
    }

    public function afterLogin()
    {
        $this->setSession();
        $this->setMenu();
    }


    public function setSession()
    {
        $session = Yii::$app->session;
        // 检查session是否开启
        if (!$session->isActive) {
            // 开启session
            $session->open();
        }
        $rule = (new AdminUser)->getUserRule();
        $authRule = AdminRule::find()
            ->select(['id', 'name'])
            ->where("id in ({$rule})")
            ->andWhere(['status' => 1])
            ->indexBy('name')
            ->asArray()->all();
        $session->set(self::AUTH_RIDS, $rule);
        $session->set(self::AUTH_RULES, $authRule);
    }

    /**
     * 缓存权限菜单
     * @return string
     * @throws \Exception
     */
    public function setMenu()
    {
        $rule = $this->getRules();
        $tree = [];
        $this->getNodeTree($rule, $tree);
        $htmlMenu = $this->getHtmlMenu($tree);
        Yii::$app->menuCache->set(self::MENU_KEY, $htmlMenu);
        return $htmlMenu;
    }

    /**
     * @return array|\yii\db\ActiveRecord[]
     * @throws \Exception
     */
    public function getRules()
    {
        $rulesId = Yii::$app->session->get(self::AUTH_RIDS);
        if (!$rulesId) {
            throw new \Exception('没有权限！');
        }
        return AdminRule::find()
            ->where(['in', 'id', explode(',', $rulesId)])
            ->andWhere(['type' => 1, 'status' => 1, 'isdelete' => 0])
            ->orderBy('sort ASC ,id DESC')
            ->asArray()->all();
    }

    /**
     * @param $list
     * @param $tree
     * @param int $pid
     */
    function getNodeTree(&$list, &$tree, int $pid = 0)
    {
        foreach ($list as $key => $value) {
            if ($pid == $value['pid']) {
                $tree[$value['id']] = $value;
                unset($list[$key]);
                $this->getNodeTree($list, $tree[$value['id']]['children'], $value['id']);
            }
        }
    }

    /**
     * @param $data
     * @param int $pid
     * @return string
     */
    public function getHtmlMenu($data, $pid = 0)
    {
        static $html = '';
        foreach ($data as $key => $val) {
            if (isset($val['children']) && !empty($val['children'])) {
                if ($pid == 0) {
                    $html .= '<el-submenu index="' . $val['id'] . '">
                            <template #title>
                                <i class="' . ($val['icon'] ?? '') . '"></i>
                                <span>' . $val['title'] . '</span>
                            </template>' . PHP_EOL;
                } else {
                    $html .= '<a href="' . ($val['name'] ?? 'javascript:void') . '"><el-submenu index="' . $val['id'] . '">
                            <template #title>' . $val['title'] . '</template></a>';
                }
                $this->getHtmlMenu($val['children'], $val['id']);
                $html .= '</el-submenu>';

            } else {
                if ($pid == 0) {
                    $html .= '<a href="' . ($val['name'] ?? 'javascript:void') . '"><el-menu-item index="' . $val['id'] . '">
                                <i class="' . ($val['icon'] ?? '') . '"></i>
                                <template #title>' . $val['title'] . '</template>
                            </el-menu-item></a>';
                } else {
                    $html .= ' <a href="' . ($val['name'] ?? 'javascript:void') . '"><el-menu-item index="' . $val['id'] . '">' . $val['title'] . '</el-menu-item></a>' . PHP_EOL;
                }

            }

        }

        return $html;

    }

}